/*
* @Author: Adolphus.Yao
* @Date:   2019-09-02 18:31:03
* @Last Modified by:   Adolphus.Yao
* @Last Modified time: 2019-09-03 15:13:08
*/
package main

import (
    "fmt"
    "strings"
    "reflect"
    "fulnero.com/test4proto/data"
    "github.com/golang/protobuf/proto"
    "github.com/golang/protobuf/ptypes"
)

func main() {
    test := &data.Test{Code: 1, Message: "test"}
    fmt.Println(fmt.Sprintf("%+v", *test))
    body, err := ptypes.MarshalAny(test)
    if nil != err {
      fmt.Sprint(err)
      return
    }
    test4Any := data.Test4Any{
        Details: body,
        Message: "test2",
    }
    fmt.Println(fmt.Sprintf("%+v", test4Any))
    typeUrl := getTypeUrl(test4Any.Details.GetTypeUrl())
    fmt.Println(typeUrl)
    test2, err := GetRPCMessageObjectByName(typeUrl)
    if nil != err {
      fmt.Sprint(err)
      return
    }
    err = ptypes.UnmarshalAny(test4Any.Details, test2)
    if nil != err {
      fmt.Sprint(err)
      return
    }
    fmt.Println(fmt.Sprintf("%+v", test2))
}

func getTypeUrl(typeUrl string) string {
    sIndex := strings.Index(typeUrl, "/")
    return typeUrl[sIndex+1:len(typeUrl)]
}

func GetRPCMessageObjectByName(msgName string) (msg proto.Message, err error) {
    msgType := proto.MessageType(msgName)
    if msgType == nil {
        err = fmt.Errorf("can‘t find message type")
        return
    }
    // msgType is pointer
    msg = reflect.Indirect(reflect.New(msgType.Elem())).Addr().Interface().(proto.Message)
    return
}